package com.ruoyi.system.service.impl.user;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.VsUser;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.config.VsDramasConfig;
import com.ruoyi.system.domain.user.VsDramasUserBank;
import com.ruoyi.system.domain.video.VsLang;
import com.ruoyi.system.mapper.config.VsDramasConfigMapper;
import com.ruoyi.system.mapper.user.VsDramasUserBankMapper;
import com.ruoyi.system.mapper.user.VsUserMapper;
import com.ruoyi.system.mapper.video.VsLangMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.user.VsDramasUserWalletApplyMapper;
import com.ruoyi.system.domain.user.VsDramasUserWalletApply;
import com.ruoyi.system.service.user.IVsDramasUserWalletApplyService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户提现Service业务层处理
 * 
 * @author zzx
 * @date 2024-07-06
 */
@Service
public class VsDramasUserWalletApplyServiceImpl implements IVsDramasUserWalletApplyService 
{
    @Autowired
    private VsDramasUserWalletApplyMapper vsDramasUserWalletApplyMapper;

    @Autowired
    private VsUserMapper vsUserMapper;

    @Autowired
    private VsLangMapper vsLangMapper;

    @Autowired
    private VsDramasConfigMapper vsDramasConfigMapper;

    @Autowired
    private VsDramasUserBankMapper vsDramasUserBankMapper;

    /**
     * 查询用户提现
     * 
     * @param id 用户提现主键
     * @return 用户提现
     */
    @Override
    public VsDramasUserWalletApply selectVsDramasUserWalletApplyById(Long id)
    {
        return vsDramasUserWalletApplyMapper.selectVsDramasUserWalletApplyById(id);
    }

    /**
     * 查询用户提现列表
     * 
     * @param vsDramasUserWalletApply 用户提现
     * @return 用户提现
     */
    @Override
    public List<VsDramasUserWalletApply> selectVsDramasUserWalletApplyList(VsDramasUserWalletApply vsDramasUserWalletApply)
    {
        return vsDramasUserWalletApplyMapper.selectVsDramasUserWalletApplyList(vsDramasUserWalletApply);
    }

    /**
     * 新增用户提现
     * 
     * @param vsDramasUserWalletApply 用户提现
     * @return 结果
     */
    @Override
    public int insertVsDramasUserWalletApply(VsDramasUserWalletApply vsDramasUserWalletApply)
    {
        return vsDramasUserWalletApplyMapper.insertVsDramasUserWalletApply(vsDramasUserWalletApply);
    }

    /**
     * 修改用户提现
     * 
     * @param vsDramasUserWalletApply 用户提现
     * @return 结果
     */
    @Override
    public int updateVsDramasUserWalletApply(VsDramasUserWalletApply vsDramasUserWalletApply)
    {
        vsDramasUserWalletApply.setUpdatetime(System.currentTimeMillis());
        return vsDramasUserWalletApplyMapper.updateVsDramasUserWalletApply(vsDramasUserWalletApply);
    }

    /**
     * 批量删除用户提现
     * 
     * @param ids 需要删除的用户提现主键
     * @return 结果
     */
    @Override
    public int deleteVsDramasUserWalletApplyByIds(Long[] ids)
    {
        return vsDramasUserWalletApplyMapper.deleteVsDramasUserWalletApplyByIds(ids);
    }

    /**
     * 删除用户提现信息
     * 
     * @param id 用户提现主键
     * @return 结果
     */
    @Override
    public int deleteVsDramasUserWalletApplyById(Long id)
    {
        return vsDramasUserWalletApplyMapper.deleteVsDramasUserWalletApplyById(id);
    }

    @Override
    public AjaxResult calculateConversionRatio(VsDramasUserWalletApply vsDramasUserWalletApply) {
        return AjaxResult.success(apply(vsDramasUserWalletApply));
    }

    @Transactional
    @Override
    public int withdrawal(VsDramasUserWalletApply vsDramasUserWalletApply) {
        VsDramasUserWalletApply apply = apply(vsDramasUserWalletApply);
        VsUser user = vsUserMapper.selectVsUserById(vsDramasUserWalletApply.getUserId());
        if(user == null){
            throw new RuntimeException("User does not exist");
        }
        if (user.getMoney() == null || user.getMoney().compareTo(BigDecimal.ZERO) == 0) {
            throw new RuntimeException("The balance is empty");
        }
        if (user.getMoney().compareTo(vsDramasUserWalletApply.getMoney()) < 0) {
            throw new RuntimeException("Insufficient balance");
        }
        VsDramasUserBank bank = new VsDramasUserBank();
        bank.setUserId(vsDramasUserWalletApply.getUserId());
        bank.setType(vsDramasUserWalletApply.getApplyType());
        List<VsDramasUserBank> userBanks = vsDramasUserBankMapper.selectVsDramasUserBankList(bank);
        if (userBanks.size() == 0) {
            throw new RuntimeException("Account information does not exist");
        }
        VsDramasUserBank userBank = userBanks.get(0);
        JSONObject payObject = new JSONObject();
        payObject.put("Real name", userBank.getRealName());
        if ("bank".equals(vsDramasUserWalletApply.getApplyType())) {
            payObject.put("Bank name", userBank.getBankName());
            payObject.put("Bank card", userBank.getCardNo());
        } else if ("wechat".equals(vsDramasUserWalletApply.getApplyType())) {
            payObject.put("Alipay account", userBank.getBankName());
            payObject.put("Payment code", userBank.getImage());
        } else if ("alipay".equals(vsDramasUserWalletApply.getApplyType())) {
            payObject.put("Alipay account", userBank.getBankName());
            payObject.put("Payment code", userBank.getImage());
        }
        long time = System.currentTimeMillis();
        apply.setUserId(vsDramasUserWalletApply.getUserId());
        apply.setApplySn("W" + time + IdUtils.fastSimpleUUID());
        apply.setApplyType(vsDramasUserWalletApply.getApplyType());
        apply.setApplyInfo(payObject.toJSONString());
        apply.setStatus(0);
        apply.setPlatform(vsDramasUserWalletApply.getPlatform());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("oper_type", "user");
        jsonObject.put("oper_id", vsDramasUserWalletApply.getUserId());
        jsonObject.put("oper_info", "用户发起提现申请");
        jsonObject.put("oper_time", time);
        apply.setCreatetime(time);
        apply.setUpdatetime(time);
        JSONArray array = new JSONArray();
        array.add(jsonObject);
        apply.setLog(array.toJSONString());
        int i = vsDramasUserWalletApplyMapper.insertVsDramasUserWalletApply(apply);
        if (i > 0) {
            VsUser updateMoney = new VsUser();
            updateMoney.setId(vsDramasUserWalletApply.getUserId());
            updateMoney.setMoney(user.getMoney().negate());
            return vsUserMapper.updateVsUserMoney(updateMoney);
        }
        return i;
    }

    private VsDramasUserWalletApply apply(VsDramasUserWalletApply vsDramasUserWalletApply) {
        VsLang lang = new VsLang();
        lang.setCurrency(vsDramasUserWalletApply.getCurrency());
        List<VsLang> langList = vsLangMapper.getVsLangList(lang);
        if (langList.isEmpty()) {
            throw new RuntimeException("Currency does not exist");
        }
        BigDecimal money = new BigDecimal(0);
        BigDecimal payMoney = new BigDecimal(0);
        Long exchangeRate = langList.get(0).getExchangeRate();
        if (vsDramasUserWalletApply.getMoney() != null) {
            money = vsDramasUserWalletApply.getMoney();
            payMoney = vsDramasUserWalletApply.getMoney().divide(BigDecimal.valueOf(exchangeRate), 2, BigDecimal.ROUND_HALF_EVEN);
        } else if (vsDramasUserWalletApply.getPayMoney() != null) {
            money = vsDramasUserWalletApply.getPayMoney().multiply(BigDecimal.valueOf(exchangeRate));
            payMoney = vsDramasUserWalletApply.getPayMoney();
        }
        VsDramasConfig config = new VsDramasConfig();
        config.setName("withdraw");
        List<VsDramasConfig> configs = vsDramasConfigMapper.selectVsDramasConfigList(config);
        if (configs.isEmpty()) {
            throw new RuntimeException("Withdrawal configuration does not exist");
        }
        Map<String, String> map = JSON.parseObject(configs.get(0).getValue(), new TypeReference<Map<String, String>>(){});
        BigDecimal serviceFee = BigDecimal.valueOf(Double.parseDouble(map.get("service_fee")));
        BigDecimal decimal = money.multiply(serviceFee);
        VsDramasUserWalletApply apply = new VsDramasUserWalletApply();
        apply.setCurrency(vsDramasUserWalletApply.getCurrency());
        apply.setExchangeRate(exchangeRate);
        apply.setMoney(money.add(decimal));
        apply.setPayMoney(payMoney);
        apply.setActualMoney(payMoney);
        apply.setChargeMoney(decimal);
        apply.setServiceFee(serviceFee);
        return apply;
    }

}
